package com.netposa.datawarehouse.bodysearch.utils;

import com.google.common.collect.Lists;

import java.util.List;

public class BitOp {
   private List<Integer> orList;

   private BitOp() {
   }

   public static BitOp create(Integer... op) {
      BitOp bitOp = new BitOp();
      bitOp.init(op);
      return bitOp;
   }

   public static List getUnion(Integer... values) {
      BitOp bitOp = new BitOp();
      bitOp.init(values);
      return bitOp.orList;
   }

   public List<Integer> involve(int value) {
      List<Integer> result = Lists.newArrayList();
      this.orList.forEach((v) -> {
         if ((value & v) == value) {
            result.add(v);
         }

      });
      return result;
   }

   private void init(Integer... op) {
      List<Integer>ops = Lists.newArrayList(op);
      this.orList = Lists.newArrayList();

      for(int i = 0; i < ops.size(); ++i) {
         this.orList.add(ops.get(i));
         this.marshalling(i, Lists.newArrayList(), ops, this.orList);
      }

   }

   private void marshalling(int self, List head, List data, List result) {
      for(int i = self + 1; i < data.size(); ++i) {
         List cResult = Lists.newArrayList(head);
         cResult.add(data.get(self));
         cResult.add(data.get(i));
         result.add(this.or(cResult));
         List headClone = Lists.newArrayList(head);
         headClone.add(data.get(self));
         this.marshalling(i, headClone, data, result);
      }

   }

   private int or(List op) {
      int tmp = 0;
      int i = 0;

      for(int size = op.size(); i < size; ++i) {
         tmp |= (Integer)op.get(i);
      }

      return tmp;
   }
}
